# 头条极速版
import json
import random
import re
import time

from PySide6.QtCore import Qt
from PySide6.QtWidgets import QTableWidgetItem

from common.mytRpc import MytRpc
from ikuai import IKuai
from utils import *


class Bytedance(object):
    def __init__(self, android, stop_event):
        print('bytedance', android)
        self.stop_event = stop_event
        self.devinfo = {}
        if DkGlobal().window:
            self.auto_id = DkGlobal().window.auto_id.text()
        else:
            self.auto_id = 4
        print("auto_id", self.auto_id)
        self.appinfo = ServerApi().get_appinfo(self.auto_id)
        print("appinfo", self.appinfo)
        # self.appinfo = {'app_name': '时尚潮流馆', 'app_id': 23, 'appid': 'ttcbaabd17549dd8e801', 'auto_id': 3, 'app_type': 1, 'number': 4}
        self.app_number = self.appinfo['number']
        self.app_type = str(self.appinfo['app_type'])
        # self.app_type = self.appinfo['app_type']
        self.sdk_http = HttpApi("http://127.0.0.1:5000")
        self.android = android
        self.finish = False
        self.user_wait = False
        self.install = {
            "tt": False,
            "js": False,
            'dy': False,
            'dy_lite': False
        }
        self.mytapi = MytRpc()
        port = int(android['RPC'].split(":")[1])
        if self.mytapi.init(android['ip'], port, 5) == True:
            if self.mytapi.check_connect_state() == True:
                self.log(f"{android['ip']}当前连接状态正常", '连接正常')
            else:
                self.log(f"{android['ip']}当前连接断开", '连接断开', 1)
        else:
            self.log("RPC连接失败", '连接失败', 1)

        self.set_table_item(5, self.app_type)
        self.set_table_item(3, self.appinfo['app_name'])
        self.update_count()

    def reset2(self):
        while self.is_run():
            print(f"持续执行了一下咯{self.stop_event.is_set()}")
            time.sleep(4)  # 模拟任务执行

    def is_run(self):
        if self.stop_event is not None:
            return not self.stop_event.is_set()
        return True

    def reset_android(self):
        # 刷新IP
        self.refresh_ip()
        res = self.sdk_http.get(f"/reset/{self.android['SERVER_IP']}/{self.android['Names']}").json()
        if res['code'] == 200:
            self.log(f"重置设备{self.android['Name']} 成功", '重置成功')
            res = self.sdk_http.get(f"/run/{self.android['SERVER_IP']}/{self.android['Names']}").json()
            if res['code'] == 200:
                self.log(f"设备{self.android['Name']}执行启动成功", '执行启动成功')
                times = 0
                while self.is_run():
                    self.log(f"设备{self.android['Name']}等待启动...", f'等待启动：{times}')
                    res = self.sdk_http.get(f"/get_android_boot_status/{self.android['SERVER_IP']}/{self.android['Names']}").json()
                    # print("res", res)
                    times += 2
                    self.time_sleep(2)
                    if times >= 50:
                        self.log(f"当前等待超时，res:{res}", '超时', 1)
                        # self.reset_android()
                        return False
                        # break
                    if res['code'] == 200:
                        break
                check_index = 0
                while self.is_run():
                    if check_index >= 20:
                        self.log('检测超出次数', '检测超次数', 1)
                        # self.reset_android()
                        # break
                        return False
                    if self.mytapi.check_connect_state() == True:
                        xml = self.mytapi.dumpNodeXml(1)
                        if xml is not False and "图库" in xml:
                            self.log("已检测到首页，重置成功", '重置成功')
                            break
                        check_index += 1
                        self.log("检测首页", '检测首页')
                        time.sleep(3)
                    else:
                        self.log("check_connect_state不为true", '重置', 1)
                        # self.reset_android()
                        # break
                        return False
                # 写入真机信息
                print("准备写入真机信息")
                res = self.set_custom_devinfo()
                if res:
                    self.auto()
                else:
                    return False

    def auto(self):
        task = {
            "1": {"name": "极速", "apk": "js"},
            "2": {"name": "头条", "apk": "tt"},
            "3": {"name": "抖音", "apk": "dy"},
            "4": {"name": "抖音极速", "apk": "dy_lite"},
        }
        # for app_type in task:
        max_count = 0
        while self.is_run() and self.app_number > 0 and self.finish == False:
            max_count += 1
            if max_count >= 6:
                return False
            res = self.install_apk(task[self.app_type]["apk"])
            if res == False:
                self.log(f"安装{task[self.app_type]['name']}失败", '安装失败', 1)
                self.finish = True
                return False
            # 打开小程序
            self.log("执行打开小程序", '执行打开小程序')
            res = self.open_min_app()
            # 看广告
            if res == True:
                self.log("当前打开小程序成功", '打开成功')
                max_count2 = 0
                while self.is_run() and self.app_number > 0 and self.finish == False:
                    max_count2 += 1
                    if max_count2 >= 6:
                        return False
                    res = self.start_click_ad()
                    if res == False:
                        self.log('看广告失败了', '头条看广告失败了')
                    else:
                        wait_time = random.randint(10, 30)
                        self.log(f'看完一条,等待{wait_time},剩余{self.app_number}', f'剩余{self.app_number}')
                        self.time_sleep(wait_time)
                if self.app_number <= 0:
                    self.finish = True
                    return True

    def open_min_app(self):
        max_count = 0
        # 执行个人中心页面等待
        if self.app_type == '1':
            # self.handle_user_wait(random.randint(60, 100))
            kongbai = 0
            while self.is_run():
                page = self.get_page_name()
                if max_count > 10:
                    self.finish = True
                    return False
                if "搜索小程序" in self.getXml():
                    selector = self.mytapi.create_selector()
                    time.sleep(0.3)
                    with selector:
                        selector.addQuery_TextEqual('搜索小程序')
                        node = selector.execQueryOne(1)
                        if node is not None:
                            node.Click_events()
                            time.sleep(1)
                        selector.addQuery_ClzEqual("android.widget.EditText")
                        node = selector.execQueryOne(1)
                        if node is not None:
                            node.Click_events()
                            time.sleep(1)
                            self.mytapi.sendText(self.appinfo['app_name'])
                            time.sleep(0.5)
                            self.mytapi.pressEnter()
                            while self.is_run():
                                if "暂无相关小程序" in self.getXml():
                                    self.open_scheme()
                                    break
                                if "tma_search_-1_0" in self.getXml():
                                    selector = self.mytapi.create_selector()
                                    with selector:
                                        selector.addQuery_TextEqual(self.appinfo['app_name'])
                                        nodes = selector.execQuery(2, 1)
                                        if (len(nodes) >= 2):
                                            nodes[1].Click_events()
                                            break
                                        else:
                                            self.open_scheme()
                                            break
                elif "查看答案" in page:
                    return True
                elif "小程序页面" in page and "查看答案" not in page:
                    self.log("在小程序页面")
                    kongbai += 1
                    if kongbai > 2:
                        self.log("页面空白5次，重新打开", '页面空白', 1)
                        self.mytapi.clickDesc("更多")
                        time.sleep(1)
                        self.mytapi.clickText("重启小程序")
                elif "头条极速首页" in page:
                    self.mytapi.clickText("未登录")
                elif "极速个人中心" in page:
                    self.mytapi.clickText("小程序")
                elif "系统首页" in page:
                    self.log("因为在系统首页而打开APP")
                    self.open_app()
                elif "小程序加载失败" in page:
                    self.finish = True
                    return False
                elif "首次小程序" in page:
                    max_count3 = 0
                    while self.is_run() and "首次小程序" in self.get_page_name():
                        self.log("首次小程序等待", "首次")
                        if max_count3 >= 30:
                            self.finish = True
                            return False
                        time.sleep(10)
                self.time_sleep(5)
                max_count += 1
            # 搜索小程序
        if self.app_type == '2':
            kongbai = 0
            while self.is_run():
                page = self.get_page_name()
                if max_count > 10:
                    self.finish = True
                    return False
                if "头条首页" in page:
                    self.mytapi.touchClick(1, 363, 100)
                    time.sleep(1)
                    self.mytapi.sendText(self.appinfo['app_name'])
                    time.sleep(1)
                    self.mytapi.pressEnter()
                    count = 0
                    while self.is_run():
                        if count > 5:
                            self.open_scheme()
                            break
                        text = f"{self.appinfo['app_name']} -小程序 举报反馈"
                        if text in self.getXml():
                            self.mytapi.clickText(text)
                            break
                        else:
                            time.sleep(2)
                            count += 1
                elif "系统首页" in page:
                    self.log("因为在系统首页而打开APP")
                    self.open_app()
                elif "头条搜索内容页" in page:
                    self.mytapi.clickText(f"{self.appinfo['app_name']} -小程序 举报反馈")
                elif "查看答案" in page:
                    return True
                elif "小程序页面" in page and "查看答案" not in page:
                    self.log("在小程序页面")
                    kongbai += 1
                    if kongbai > 2:
                        self.log("页面空白5次，重新打开", '页面空白', 1)
                        self.mytapi.clickDesc("更多")
                        time.sleep(1)
                        self.mytapi.clickText("重启小程序")
                elif "小程序加载失败" in page:
                    # TODO 这里加载失败处理
                    self.finish = True
                    return False
                elif "首次小程序" in page:
                    max_count3 = 0
                    while self.is_run() and "首次小程序" in self.get_page_name():
                        self.log("首次小程序等待", "首次")
                        if max_count3 >= 30:
                            self.finish = True
                            return False
                        time.sleep(10)
                time.sleep(5)
                max_count += 1
        if self.app_type == '3':
            # 抖音
            pass
        if self.app_type == '4':
            pass

    def start_click_ad(self):
        # 首先点击左边空白然后，然后点击查看答案关闭弹窗
        max_count = 0
        while self.is_run():
            if max_count > 10:
                self.finish = True
                return False
            page = self.get_page_name()
            if "小程序页面" in page or "查看答案" in page or "广告弹窗确认" in page or "答案弹窗" in page:
                self.mytapi.touchClick(1, 690, 635)
                self.time_sleep(2)
                self.mytapi.clickText("确认")
                self.time_sleep(2)
                self.mytapi.clickText("查看答案")
                self.log("点击查看答案", '查看答案')
                time_count = 0
                while self.is_run():
                    if time_count >= 15:
                        self.log('看广告超出15次，重新执行', '超出15次', 1)
                        return True
                    page = self.get_page_name()
                    if "头条极速首页" in page or "头条首页" in page or "极速个人中心" in page or "首页" in page:
                        self.open_scheme()
                    elif "广告弹窗确认" in page and "广告页面" not in page:
                        self.log("点击广告弹窗确认", "确认弹窗")
                        self.mytapi.clickText("确定")
                    elif "直播完整功能加载" in self.getXml():
                        self.mytapi.pressBack()
                    elif "免广告答案" in self.getXml():
                        self.log("当前没有适合的广告或者报错了", '报错了', 1)
                        self.finish = True
                        return False
                    elif "广告内页":
                        self.log("进入了广告内页", "广告内页")
                        self.time_sleep(3)
                        self.mytapi.clickDesc("返回")
                        self.time_sleep(3)
                    self.log("判断看完广告", '判断看完广告')
                    if "广告失败" in page:
                        self.mytapi.touchClick(1, 648, 100)
                        self.time_sleep(2)
                        self.mytapi.clickText("坚持退出")
                        return False
                    if "看完广告" in page:
                        self.time_sleep(random.randint(10, 20))
                        self.mytapi.touchClick(1, 48, 112)
                        self.time_sleep(5)
                        self.log("看完广告，领取奖励页面", "看完广告")
                        self.time_sleep(3)
                        self.mytapi.clickText("领取成功")
                        self.app_number -= 1
                        self.log(f"{self.app_type}看完1条，还剩{self.app_number}条", '看完1次')
                        self.update_count()
                        # ServerApi().set_devinfo_used(self.appinfo['app_id'], self.devinfo['devinfo_id'], self.devinfo['auto_id'], self.app_type)
                        ServerApi().set_devinfo_used(self.appinfo, self.devinfo)
                        max_count2 = 0
                        while self.is_run():
                            page = self.get_page_name()
                            if max_count2 > 10:
                                self.stop_app()
                                time.sleep(2)
                                self.open_scheme()
                                self.log("超出次数了，重新打开小程序", '重新打开', 1)
                                self.time_sleep(5)
                                return True
                            if "查看答案" in page or "答案弹窗" in page:
                                return True
                            if "登录页" in page or "极速个人中心" in page:
                                self.stop_app()
                                time.sleep(2)
                                self.open_scheme()
                                self.log("到了登录页重新打开小程序", '重新打开', 1)
                                self.time_sleep(5)
                            self.time_sleep(5)
                            self.log("看完广告循环判断", '看完广告循环')
                            max_count2 += 1
                    time.sleep(3)
                    max_count += 1
                    time_count += 1
                    self.log(f"循环判断广告点击，当前次数{time_count}次", '判断广告次数')

    def open_scheme(self):
        scheme_type = {
            "1": 'snssdk35',
            "2": 'snssdk141',
            "3": 'snssdk1128',
            "4": 'snssdk2329',
        }
        scheme = f"{scheme_type[self.app_type]}://microapp?app_id={self.appinfo['appid']}&bdp_log=%7B%22launch_from%22%3A%22ad%22%2C%22location%22%3A%22%22%7D&scene=0&start_page=pages%2Fquestion%2Fad%3F&version=v2&version_type=current&bdpsum=880db2b"
        cmd = f"am start -a android.intent.action.VIEW -d \"{scheme}\""
        return self.mytapi.exec_cmd(cmd)

    def handle_user_wait(self, wait_time=120):
        self.open_app()
        while self.is_run():
            selector = self.mytapi.create_selector()
            time.sleep(0.3)
            with selector:
                # 同意按钮检测
                selector.addQuery_DescEqual('同意，按钮')
                node = selector.execQueryOne(1)
                if node is not None:
                    node.Click_events()
                    time.sleep(1)
                # 【抖音】同意按钮检测
                selector.addQuery_TextEqual('同意')
                node = selector.execQueryOne(1)
                if node is not None:
                    node.Click_events()
                    time.sleep(1)
                # 【抖音】上滑查看更多视频
                selector.addQuery_TextEqual('上滑查看更多视频')
                node = selector.execQueryOne(1)
                if node is not None:
                    self.mytapi.swipe(1, 200, 500, 200, 200, 300)
                    time.sleep(1)
                    break
                # 红包弹窗检测
                selector.addQuery_TextEqual('恭喜！你收到一个现金红包')
                node = selector.execQueryOne(1)
                if node is not None:
                    self.mytapi.exec_cmd("input keyevent KEYCODE_BACK")
                # 个人中心检测
                selector.addQuery_TextEqual('未登录')
                node = selector.execQueryOne(1)
                if node is not None:
                    self.log(f"个人中心停留{wait_time}s", '个人中心停留')
                    node.Click_events()
                    selector.addQuery_TextEqual("小程序")
                    node = selector.execQueryOne(1)
                    if node is not None:
                        time.sleep(wait_time)
                        break

    def getXml(self):
        res = self.mytapi.dumpNodeXml(True)
        if res == False:
            self.log("无法获取到xml", '无法获取xml', 1)
            self.time_sleep(2)
            self.reset_android()
            return False
        else:
            return res

    def get_page_name(self):
        if self.mytapi == None:
            return []
        pages = []
        xml = str(self.getXml())
        # print(xml)
        if 'text="搜索框，' in xml:
            pages.append("头条搜索内容页")
        if "流畅模式" in xml:
            self.mytapi.clickText("取消")
        if "文件管理" in xml and "扩展服务" in xml:
            pages.append("系统首页")
        if "关注" in xml and "推荐" in xml or ("发现" in xml and "视频" in xml):
            pages.append("头条极速首页")
        if "个人信息保护指引" in xml:
            pages.append("隐私协议")
            print("发现隐私协议")
            self.log("发现隐私协议", '隐私协议')
            self.time_sleep(3)
            self.mytapi.clickText("同意")
        if "抖音号快捷登录" in xml or "登录立即领红包" in xml or "登录体验 完整功能" in xml:
            pages.append("登录页")
            self.mytapi.pressBack()
        if "你收到一个现金红" in xml or "恭喜获得现金红包" in xml or "提现至支付宝" in xml or "开红包" in xml:
            pages.append("红包")
            self.log("发现红包弹窗", '红包')
            self.mytapi.clickDesc("关闭")
            self.mytapi.clickId("com.ss.android.ugc.aweme.lite:id/c2v")
            self.mytapi.touchClick(1, 615, 285)
        if ("头条" in xml and "我的" in xml) or ("头条" in xml and "未登录" in xml):
            pages.append("头条首页")
        if "登录体验 完整功能" in xml:
            pages.append("头条登录页")
        if self.mytapi.check_connect_state() == True:
            res = self.mytapi.getNodeByText("未登录")
            if res != None:
                if json.loads(res)[0]['selected']:
                    pages.append("极速个人中心")
        if "microapp_m_loading_icon" in xml and "小程序加载失败" not in xml:
            pages.append("加载LOGO")
        if "首次使用小程序" in xml:
            pages.append("首次小程序")
        if "正在加载页面" in xml:
            pages.append("加载组件")
        if "点击退出小程序" in xml:
            pages.append("小程序页面")
        if "查看答案" in xml:
            pages.append("查看答案")
        if "查看答案需要看广告" in xml:
            pages.append("广告弹窗确认")
        if "广告" in xml and "开启声音" in xml:
            pages.append("广告页面")
        if "广告" in xml and "秒后可领奖励" in xml:
            pages.append("等待广告")
        if (
                "返回" in xml
                and "bdp_titlebar_back" not in xml
                and "搜索" not in xml
                and "登录立即领红包" not in xml
                or "com.ss.android.article.lite:id/b7h" in xml

        ):
            pages.append("广告内页")
        if "领取成功" in xml:
            pages.append("看完广告")
        if "立即下载" in xml:
            pages.append("立即下载")
        if "视频加载失败，请重试" in xml:
            pages.append('广告失败')
        if "升级版本" in xml:
            self.log("提示升级版本，自动关闭", '升级版本')
            self.time_sleep(3)
            self.mytapi.clickDesc('关闭')

        if "小程序加载失败" in xml:
            pages.append("小程序加载失败")
        if "确认" in xml and "正确答案" in xml:
            pages.append("答案弹窗")
        # print("get_page_name", self.android['Name'], pages)
        return pages

    def install_apk(self, name='js'):
        res = self.sdk_http.get(f"/install_apk/{self.android['SERVER_IP']}/{self.android['Names']}?local=C:/apk/{name}.apk").json()
        print('install', res)
        if res['code'] == 0:
            self.log(f"{self.android['Name']} 安装 - {name} 成功", '安装成功')
            return True
        else:
            self.log(f"{self.android['Name']} 安装 - {name} 失败", '安装失败')
            return False

    def open_app(self):
        pkgs = {
            "1": "com.ss.android.article.lite",
            "2": "com.ss.android.article.news",
            "3": "com.ss.android.ugc.aweme",
            "4": "com.ss.android.ugc.aweme.lite",
        }
        self.mytapi.openApp(pkgs[self.app_type])
        self.log(f'正在打开程序{self.app_type}', f'打开程序{self.app_type}')
        self.log(f"self.is_run()-:{self.is_run()}")

    def stop_app(self):
        pkgs = {
            "1": "com.ss.android.article.lite",
            "2": "com.ss.android.article.news",
            "3": "com.ss.android.ugc.aweme",
            "4": "com.ss.android.ugc.aweme.lite",
        }
        self.mytapi.stopApp(pkgs[self.app_type])
        self.log('正在关闭程序', '关闭程序')
        self.time_sleep(3)

    # 刷新IP
    def refresh_ip(self, reason=""):
        self.log(f'{reason}刷新当前ip', f'{reason}刷新IP')
        IKuai().refresh_ip(self.android, True)
        self.time_sleep(3)

    def time_sleep(self, _time):
        while self.is_run():
            if _time <= 0:
                break
            time.sleep(1)
            _time -= 1
            self.set_table_item(7, _time)

    def set_custom_devinfo(self):
        self.log(f"{self.android['Name']}准备写入真机信息", '写入真机信息')
        # try:
        # self.devinfo = ServerApi().get_android_devinfo(self.auto_id, self.appinfo['app_id'])
        content = getDevinfoData("devinfo/data")
        device = getDeviceData()
        print("信息", content, device)
        if content is False or device is False:
            while True:
                self.log("当前真机信息已用完", '无真机')
                self.time_sleep(50)
        # content = self.devinfo['content']
        # self.log(f"真机信息记录：device_id:{self.devinfo['device_id']} - devinfo_id:{self.devinfo['devinfo_id']}")
        # 发送请求
        url = f"set_custom_devinfo/{self.android['SERVER_IP']}/{self.android['Names']}?androidId={device['AndroidID']}&oaid={device['OAID']}"
        print("url", url)
        # print(self.devinfo)
        res = self.sdk_http.post(url, None, content).json()
        print("res", res)
        if res['code'] == 200:
            self.log(f"{self.android['Name']}写入真机信息成功", '真机写入成功')
            res = self.sdk_http.post(url, None, content).json()
            self.log(f'写入第二次{res["code"]}')
            return True
        else:
            self.log(f"{self.android['Name']}写入真机信息失败", '真机写入失败', 1)
            return False
        # except Exception as e:
        #     print(f"auto 函数中发生异常: {e}")
        #     self.set_custom_devinfo()
        # pass

    # 记录日志
    def log(self, content, status=None, error=0):
        type = ''
        if error == 1:
            type = 'error'

        content = f"{self.android['Name']}-{self.appinfo['app_name']}:{content}"
        print(f"content:{type} {content} status:{status}")
        if status:
            self.set_android_status(status)
            pass
        if content:
            win_log(content, type, self.android['Name'])

    # 设置安卓机状态
    def set_android_status(self, status):
        if DkGlobal().android_docker != None and DkGlobal().body != None:
            keys = list(DkGlobal().android_docker.android_list.keys())
            row = keys.index(self.android['ip'])
            item = QTableWidgetItem(str(status))  # 将数据转换成字符串形式
            item.setTextAlignment(Qt.AlignCenter)
            DkGlobal().body.tableWidget.setItem(row, 6, item)

    # 设置表格
    def set_table_item(self, role, item):
        if DkGlobal().android_docker != None and DkGlobal().body != None:
            # self.app_type = item
            keys = list(DkGlobal().android_docker.android_list.keys())
            row = keys.index(self.android['ip'])
            item = QTableWidgetItem(str(item))
            item.setTextAlignment(Qt.AlignCenter)
            DkGlobal().body.tableWidget.setItem(row, role, item)

    # 更新表格统计
    def update_count(self):
        self.set_table_item(1, self.app_number)


if __name__ == '__main__':
    with open('log/android_list.json', 'r', encoding='utf-8') as file:
        data = json.load(file)
    androids = list(data.values())
    self = Bytedance(androids[3], None)
    print(self.getXml())
    print(self.get_page_name())
    # print(self.android["Name"])

    # ounds = "[570,240][660,330]"
    # self.mytapi.touchClick(1,615,285)
